package com.augurit.common.common.http.kt.api

import com.augurit.common.common.http.kt.model.Result
import com.augurit.common.common.http.kt.request.*
import java.lang.reflect.Type

/**
 *  author : yanghaozhang
 *  date : 2022/5/5 18:10
 *  description :
 */
class ApiManager private constructor() : TaskFactory.Convenience {

    override fun <OutputData> get(
        platform: IPlatFormStrategy,
        type: Type,
        path: String,
        parameters: ExtraParam?,
        headers: Map<String, String>?,
    ): IApiTask<String, Result<OutputData, Exception>> {
        return request(platform, type, Method.GET, path, parameters, headers)
    }

    override fun <OutputData> post(
        platform: IPlatFormStrategy,
        type: Type,
        path: String,
        parameters: ExtraParam?,
        headers: Map<String, String>?,
    ): IApiTask<String, Result<OutputData, Exception>> {
        return request(platform, type, Method.POST, path, parameters, headers)
    }

    override fun <OutputData> request(
        platform: IPlatFormStrategy,
        type: Type,
        method: Method,
        path: String,
        parameters: ExtraParam?,
        headers: Map<String, String>?
    ): IApiTask<String, Result<OutputData, Exception>> {
        return request(DefaultRequest(platform, method, path, parameters, headers ?: emptyMap()), ApiTransformImpl(type))
    }

    override fun <Response, OutputData> request(
        platform: IPlatFormStrategy,
        serviceBlock: suspend IPlatFormStrategy.() -> Response,
        type: Type,
    ): IApiTask<Response, Result<OutputData, Exception>> {
        return request(
            CustomRequest(platform, serviceBlock),
            ApiTransformImpl(type)
        )
    }

    override fun <Response, OutputData> request(
        request: RequestConvertible<Response>,
        apiTransform: IApiTransform<Response, Result<OutputData, Exception>>
    ): IApiTask<Response, Result<OutputData, Exception>> {
        return DirectApiImpl(request, apiTransform)
    }

    companion object {
        val instance = ApiManager()
    }
}